package com.datseek.iot.rule.manager.executor;

import com.alibaba.fastjson.JSON;
import com.datseek.iot.rule.manager.entity.RuleExecuteGlobal;
import com.datseek.iot.rule.manager.entity.RuleExecutorResult;
import com.datseek.iot.rule.manager.entity.fact.BaseFact;
import lombok.extern.slf4j.Slf4j;
import org.drools.compiler.kproject.ReleaseIdImpl;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.ReleaseId;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.StatelessKieSession;

import java.util.Objects;

/**
 * @author cc
 * @Title: 规则执行器
 * @Description: 规则执行器
 * @date 2021/9/175:32 下午
 * @since 1.0
 */
@Slf4j
public class RuleExecutor {

    static ReleaseId releaseId = new ReleaseIdImpl("com.lgp.droolsdrt", "drools-drt", "1.0");
    private static KieBase kieBase;

    /**
     * 单例
     * @return
     */
    public static KieBase getKieBase(){
        if(Objects.isNull(kieBase)){
            KieServices kieServices = KieServices.Factory.get();
            KieContainer kieContainer = kieServices.newKieContainer(releaseId);
            kieBase = kieContainer.getKieBase();
        }
        return kieBase;
    }

    /**
     * 更新kieBase
     * @return
     */
    public static KieBase updateKieBase(){
        kieBase = null;
        return getKieBase();
    }

    /**
     *   执行规则
     *  KieBase被抽取
     * @param fact
     * @param messageId
     * @return
     */
    public static RuleExecutorResult execute(BaseFact fact, String messageId) {
        log.info("RuleExecutor|execute|fact={}", JSON.toJSON(fact));
        StatelessKieSession statelessKieSession = getKieBase().newStatelessKieSession();
        RuleExecuteGlobal global = new RuleExecuteGlobal();
        global.setClientId(fact.getClientId());
        global.setMessageId(messageId);
        global.setFact(fact);
        global.setResult(new RuleExecutorResult());
        statelessKieSession.getGlobals().set("globalParams", global);
        statelessKieSession.execute(fact);
        return global.getResult();
    }

    public static ReleaseId getReleaseId(){
        return releaseId;
    }

}
